package cn.quevo.springmvc.spring.boot.autoconfigure;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.filter.HttpPutFormContentFilter;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.fasterxml.jackson.databind.ObjectMapper;

import cn.quevo.core.lang.StringUtils;

@Configuration
@EnableWebMvc
@EnableConfigurationProperties(SpringMVCProperties.class)
public class SpringMvcAutoConfiguration implements WebMvcConfigurer {

    @Autowired
    private SpringMVCProperties properties;

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.setUseSuffixPatternMatch(false);
    }

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.favorParameter(properties.isFavorParameter());
        configurer.favorPathExtension(properties.isFavorPathExtension());
        configurer.ignoreAcceptHeader(properties.isIgnoreAcceptHeader());
        configurer.defaultContentType(MediaType.APPLICATION_JSON_UTF8);
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable(properties.getDefaultServlet());
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
        if (properties == null || StringUtils.isBlank(properties.getStatics())) {
            return;
        }
        for (String res : properties.getStatics()) {
            String[] mapp = res.split("=");
            if (mapp.length < 2) {
                continue;
            }
            registry.addResourceHandler(mapp[0].trim()).addResourceLocations(mapp[1].trim());
        }
    }

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(mappingJackson2HttpMessageConverter());
    }

    @Bean
    @Order(5)
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(
                new ObjectMapper());
        return mappingJackson2HttpMessageConverter;
    }

    @Bean
    public FilterRegistrationBean<HiddenHttpMethodFilter> hiddenHttpMethodFilter() {
        FilterRegistrationBean<HiddenHttpMethodFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new HiddenHttpMethodFilter());
        registration.addUrlPatterns("/*");
        registration.setName("hiddenHttpMethodFilter");
        return registration;
    }
    
    @Bean
    public FilterRegistrationBean<HttpPutFormContentFilter> httpPutFormContentFilter() {
        FilterRegistrationBean<HttpPutFormContentFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new HttpPutFormContentFilter());
        registration.addUrlPatterns("/*");
        registration.setName("httpPutFormContentFilter");
        return registration;
    }
    
    /*
     * @Bean
     * 
     * @Order(6) public MarshallingHttpMessageConverter
     * marshallingHttpMessageConverter() { MarshallingHttpMessageConverter
     * marshallingHttpMessageConverter = new MarshallingHttpMessageConverter();
     * XStreamMarshaller marshaller = new XStreamMarshaller();
     * marshaller.setAutodetectAnnotations(true);
     * marshallingHttpMessageConverter.setMarshaller(marshaller); return
     * marshallingHttpMessageConverter; }
     */
}
